"""
@Author：WangYuXiang
@E-mile：Hill@3io.cc
@CreateTime：2021/3/24 16:34
@DependencyLibrary：无
@MainFunction：无
@FileDoc：
    view.py
    文件说明
@ChangeHistory:
    datetime action why
    example:
    2021/3/24 16:34 change 'Fix bug'

"""
import datetime

import jwt
from srf.views import APIView
from common.auth.models import UserModel
from common.auth.serializers import AdminSiteLoginByAPSerializer, AdminSiteLoginByTRSerializer
from common.utils.authentication import TemporaryTokenAuthenticate
from srf.status import HttpStatus


class LoginByAP(APIView):
    """
    使用 account 和 password 登录
    还需要继续选择 Role
    """

    async def post(self, request, *args, **kwargs):
        ap_login = AdminSiteLoginByAPSerializer(data=request.data)
        if not await ap_login.is_valid():
            return self.error_json_response(data=ap_login.errors, http_status=HttpStatus.HTTP_200_OK)

        data = ap_login.validated_data
        account = data.get('account')
        password = data.get('pwd')
        user = await UserModel.filter(account=account).first()
        if not user:
            return self.error_json_response(msg='账号或密码错误')
        if not user.check_password(password):
            return self.error_json_response(msg='账号或密码错误')
        if not user.is_active:
            return self.error_json_response(msg='账号已被封禁，请联系管理员')
        user.last_login_datetime = user.login_datetime
        user.login_datetime = datetime.datetime.now()
        await user.save()
        res_data = await AdminSiteLoginByAPSerializer(instance=user).data
        token = self.general_temporary_token(user)
        res_data.update({
            'token': token,
        })
        return self.success_json_response(data=res_data)

    def general_temporary_token(self, user):
        """生成临时Token"""
        token_secret = self.app.config.TOKEN_SECRET
        data = {
            'user_id': user.pk,
            'role_id': None,
            "exp": datetime.datetime.utcnow() + datetime.timedelta(seconds=30),
            'iat': datetime.datetime.now(),  # 开始时间
            'iss': user.account
        }
        return jwt.encode(data, token_secret, algorithm='HS256')


class LoginByTR(APIView):
    authentication_classes = (TemporaryTokenAuthenticate,)

    async def post(self, request, *args, **kwargs):
        tr_login = AdminSiteLoginByTRSerializer(data=request.data, context={'view': self, 'request': request})
        if not await tr_login.is_valid():
            return self.error_json_response(data=tr_login.errors, http_status=HttpStatus.HTTP_200_OK)

        data = tr_login.validated_data
        user = request.user
        role_id = data.get('role_id')
        user.now_role_id = role_id
        token = self.general_token(user, role_id)
        await user.save()
        permissions = await user.permissions_code()

        return self.success_json_response(data={
            'token': token,
            'user_info': {
                'account': user.account,
                'nickname': user.nickname,
            },
            'roleSign': role_id,
            'permissions': permissions
        })

    def general_token(self, user, role_id):
        """生成长效Token"""
        token_secret = self.app.config.TOKEN_SECRET
        data = {
            'user_id': user.pk,
            'role_id': role_id,
            "exp": datetime.datetime.utcnow() + datetime.timedelta(seconds=60 * 60 * 24 * 7),
            'iat': datetime.datetime.now(),  # 开始时间
            'iss': user.account
        }
        return jwt.encode(data, token_secret, algorithm='HS256')
